home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C; tab-width: 4 -*- */
- /* sproingies.c - 3D sproingies */
-
- #if !defined( lint ) && !defined( SABER )
- static const char sccsid[] = "@(#)sproingies.c 4.04 97/07/28 xlockmore";
-
- #endif
-
- /*-
- * sproingies.c - Copyright 1996 by Ed Mackey, freely distributable.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * This file is provided AS IS with no warranties of any kind. The author
- * shall have no liability with respect to the infringement of copyrights,
- * trade secrets or any patents by this file or any part thereof. In no
- * event will the author be liable for any lost revenue or profits or
- * other special, indirect and consequential damages.
- *
- * Revision History:
- * 07-Dec-96: Written.
- */
-
- #include <OpenGL/gl.h>
- #include <OpenGL/glu.h>
-
- #include <stdio.h>
-
- #include "buildlwo.h"
-
- #define MAXSPROING 100
- #define T_COUNT 40
- #define BOOM_FRAME 50
-
- struct sPosColor {
- int x, y, z, frame, life;
- GLfloat r, g, b;
- };
-
- int rotx, roty, dist, wireframe, flatshade, groundlevel,
- maxsproingies, mono_sp;
- int sframe, target_rx, target_ry, target_dist, target_count;
- GLuint sproingies[6], TopsSides, SproingieBoom;
- struct sPosColor *positions;
- static int active_screens = 0;
-
- void SproingieSwap(void);
-
- extern struct lwo LWO_s1_1, LWO_s1_2, LWO_s1_3, LWO_s1_4;
- extern struct lwo LWO_s1_5, LWO_s1_6, LWO_s1_b;
-
- #include <stdlib.h>
-
- #define LRAND rand
-
- #define MAXRAND RAND_MAX
-
-
- static int
- myrand(int range)
- {
- return ((int) (((float) range) * LRAND() / (MAXRAND)));
- }
-
- static GLuint
- build_TopsSides(int wireframe)
- {
- GLuint dl_num = 0;
- GLfloat mat_color[4] = {0.0, 0.0, 0.0, 1.0};
-
- dl_num = glGenLists(2);
- if (!dl_num)
- return (0); /* 0 means out of display lists. */
-
- /* Surface: Tops */
- glNewList(dl_num, GL_COMPILE);
- mat_color[0] = 0.392157;
- mat_color[1] = 0.784314;
- mat_color[2] = 0.941176;
- if (wireframe)
- glColor3fv(mat_color);
- else {
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_color);
- }
- glEndList();
-
- /* Surface: Sides */
- glNewList(dl_num + 1, GL_COMPILE);
- mat_color[0] = 0.156863;
- mat_color[1] = 0.156863;
- mat_color[2] = 0.392157;
- if (wireframe)
- glColor3fv(mat_color);
- else {
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_color);
- }
- glEndList();
- return (dl_num);
- }
-
- static void
- LayGround(int sx, int sy, int sz, int width, int height)
- {
- int x, y, z, w, h;
- GLenum begin_polygon;
-
- if (wireframe)
- begin_polygon = GL_LINE_LOOP;
- else
- begin_polygon = GL_POLYGON;
-
- if (!wireframe) {
- if (!mono_sp)
- glCallList(TopsSides); /* Render the tops */
- glNormal3f(0.0, 1.0, 0.0);
-
- for (h = 0; h < height; ++h) {
- x = sx + h;
- y = sy - (h << 1);
- z = sz + h;
- for (w = 0; w < width; ++w) {
- glBegin(begin_polygon);
- glVertex3i(x, y, z);
- glVertex3i(x, y, z - 1);
- glVertex3i(x + 1, y, z - 1);
- glVertex3i(x + 1, y, z);
- glEnd();
- glBegin(begin_polygon);
- glVertex3i(x + 1, y - 1, z);
- glVertex3i(x + 1, y - 1, z - 1);
- glVertex3i(x + 2, y - 1, z - 1);
- glVertex3i(x + 2, y - 1, z);
- glEnd();
- ++x;
- --z;
- }
- }
- }
- if (!mono_sp)
- glCallList(TopsSides + 1); /* Render the sides */
- if (!wireframe)
- glNormal3f(0.0, 0.0, 1.0);
-
- for (h = 0; h < height; ++h) {
- x = sx + h;
- y = sy - (h << 1);
- z = sz + h;
- for (w = 0; w < width; ++w) {
- glBegin(begin_polygon);
- glVertex3i(x, y, z);
- glVertex3i(x + 1, y, z);
- glVertex3i(x + 1, y - 1, z);
- glVertex3i(x, y - 1, z);
- glEnd();
- glBegin(begin_polygon);
- glVertex3i(x + 1, y - 1, z);
- glVertex3i(x + 2, y - 1, z);
- glVertex3i(x + 2, y - 2, z);
- glVertex3i(x + 1, y - 2, z);
- /*-
- * PURIFY 4.0.1 reports an unitialized memory read on the next line when using
- * MesaGL 2.2 and -mono_sp. This has been fixed in MesaGL 2.3 and later. */
- glEnd();
- ++x;
- --z;
- }
- }
-
- /* Render the other sides */
- if (!wireframe)
- glNormal3f(1.0, 0.0, 0.0);
-
- for (h = 0; h < height; ++h) {
- x = sx + h;
- y = sy - (h << 1);
- z = sz + h;
- for (w = 0; w < width; ++w) {
- glBegin(begin_polygon);
- glVertex3i(x + 1, y, z);
- glVertex3i(x + 1, y, z - 1);
- glVertex3i(x + 1, y - 1, z - 1);
- glVertex3i(x + 1, y - 1, z);
- glEnd();
- glBegin(begin_polygon);
- glVertex3i(x + 2, y - 1, z);
- glVertex3i(x + 2, y - 1, z - 1);
- glVertex3i(x + 2, y - 2, z - 1);
- glVertex3i(x + 2, y - 2, z);
- glEnd();
- ++x;
- --z;
- }
- }
-
- if (wireframe) {
- if (!mono_sp)
- glCallList(TopsSides); /* Render the tops */
-
- for (h = 0; h < height; ++h) {
- x = sx + h;
- y = sy - (h << 1);
- z = sz + h;
- for (w = 0; w < width; ++w) {
- glBegin(begin_polygon);
- glVertex3i(x, y, z);
- glVertex3i(x, y, z - 1);
- glVertex3i(x + 1, y, z - 1);
- glVertex3i(x + 1, y, z);
- glEnd();
- glBegin(begin_polygon);
- glVertex3i(x + 1, y - 1, z);
- glVertex3i(x + 1, y - 1, z - 1);
- glVertex3i(x + 2, y - 1, z - 1);
- glVertex3i(x + 2, y - 1, z);
- glEnd();
- ++x;
- --z;
- }
- }
- }
- }
-
- #define RESET_SPROINGIE (-30 + myrand(28))
-
- static void
- AdvanceSproingie(int t)
- {
- int g_higher, g_back, t2;
- struct sPosColor *thisSproingie = &(positions[t]);
- struct sPosColor *S2 = &(positions[0]);
-
- if (thisSproingie->life > 0) {
- if ((++(thisSproingie->frame)) > 11) {
- if (thisSproingie->frame >= BOOM_FRAME) {
- if ((thisSproingie->r -= 0.08) < 0.0)
- thisSproingie->r = 0.0;
- if ((thisSproingie->g -= 0.08) < 0.0)
- thisSproingie->g = 0.0;
- if ((thisSproingie->b -= 0.08) < 0.0)
- thisSproingie->b = 0.0;
- if ((--(thisSproingie->life)) < 1) {
- thisSproingie->life = RESET_SPROINGIE;
- }
- return;
- }
- thisSproingie->x += 1;
- thisSproingie->y -= 2;
- thisSproingie->z += 1;
- thisSproingie->frame = 0;
-
- for (t2 = 0; t2 < maxsproingies; ++t2) {
- if ((t2 != t) && (thisSproingie->x == S2->x) &&
- (thisSproingie->y == S2->y) && (thisSproingie->z == S2->z) &&
- (S2->life > 10) && (S2->frame < 6)) {
- #if 0
- if (thisSproingie->life > S2->life) {
- S2->life = 10;
- } else {
- #endif
- if (thisSproingie->life > 10) {
- thisSproingie->life = 10;
- thisSproingie->frame = BOOM_FRAME;
- if ((thisSproingie->r += 0.5) > 1.0)
- thisSproingie->r = 1.0;
- if ((thisSproingie->g += 0.5) > 1.0)
- thisSproingie->g = 1.0;
- if ((thisSproingie->b += 0.5) > 1.0)
- thisSproingie->b = 1.0;
- }
- #if 0
- }
- #endif
- }
- ++S2;
- }
- }
- if (!((thisSproingie->life == 10) &&
- (thisSproingie->frame > 0) &&
- (thisSproingie->frame < BOOM_FRAME))) {
- if ((--(thisSproingie->life)) < 1) {
- thisSproingie->life = RESET_SPROINGIE;
- } else if (thisSproingie->life < 9) {
- thisSproingie->frame -= 2;
- }
- } /* else wait here for frame 0 to come about. */
- } else if (++(thisSproingie->life) >= 0) {
- if (t > 1) {
- g_higher = -3 + myrand(5);
- g_back = -2 + myrand(5);
- } else if (t == 1) {
- g_higher = -2 + myrand(3);
- g_back = -1 + myrand(3);
- } else {
- g_higher = -1;
- g_back = 0;
- }
-
- thisSproingie->x = (-g_higher - g_back);
- thisSproingie->y = (g_higher << 1);
- thisSproingie->z = (g_back - g_higher);
- thisSproingie->life = 40 + myrand(200);
- thisSproingie->frame = -10;
- thisSproingie->r = (GLfloat) (40 + myrand(200)) / 255.0;
- thisSproingie->g = (GLfloat) (40 + myrand(200)) / 255.0;
- thisSproingie->b = (GLfloat) (40 + myrand(200)) / 255.0;
-
- for (t2 = 0; t2 < maxsproingies; ++t2) {
- if ((t2 != t) && (thisSproingie->x == S2->x) &&
- (thisSproingie->y == S2->y) && (thisSproingie->z == S2->z) &&
- (S2->life > 10) && (S2->frame < 0)) {
- /* If one is already being born, just wait. */
- thisSproingie->life = -1;
- }
- ++S2;
- }
- }
- }
-
- static void
- NextSproingie()
- {
- int ddx, t;
- struct sPosColor *thisSproingie = &(positions[0]);
-
- if (++sframe > 11) {
- sframe = 0;
- for (t = 0; t < maxsproingies; ++t) {
- thisSproingie->x -= 1;
- thisSproingie->y += 2;
- thisSproingie->z -= 1;
- ++thisSproingie;
- }
- }
- for (t = 0; t < maxsproingies; ++t) {
- AdvanceSproingie(t);
- }
-
- if (target_count < 0) { /* track to current target */
- if (target_rx < rotx)
- --rotx;
- else if (target_rx > rotx)
- ++rotx;
-
- if (target_ry < roty)
- --roty;
- else if (target_ry > roty)
- ++roty;
-
- ddx = (target_dist - dist) / 8;
- if (ddx)
- dist += ddx;
- else if (target_dist < dist)
- --dist;
- else if (target_dist > dist)
- ++dist;
-
- if ((target_rx == rotx) && (target_ry == roty) &&
- (target_dist == dist)) {
- target_count = T_COUNT;
- if (target_dist <= 32)
- target_count >>= 2;
- }
- } else if (--target_count < 0) { /* make up new target */
- target_rx = myrand(100) - 35;
- target_ry = -myrand(90);
- target_dist = 32 << myrand(2); /* could be 32, 64, or 128, (previously or 256) */
-
- if (target_dist >= dist) /* no duplicate distances */
- target_dist <<= 1;
- }
- /* Otherwise just hang loose for a while here */
- }
-
- #ifdef __AUXFUNCS__
- void
- PrintEm(void)
- {
- int t, count = 0;
-
- for (t = 0; t < maxsproingies; ++t) {
- if (positions[t].life > 0)
- ++count;
- }
- (void) printf("RotX: %d, RotY: %d, Dist: %d. Targets: X %d, Y %d, D %d. Visible: %d\n",
- rotx, roty, dist, target_rx, target_ry, target_dist, count);
- }
-
- void
- ResetEm(void)
- {
- int t;
-
- for (t = 0; t < maxsproingies; ++t) {
- positions[t].x = 0;
- positions[t].y = 0;
- positions[t].z = 0;
- positions[t].life = -2;
- positions[t].frame = 0;
- }
- }
-
- void
- distAdd(void)
- {
- if (dist < (1 << 16 << 4))
- dist <<= 1;
- }
-
- void
- distSubtract(void)
- {
- if (dist > 1)
- dist >>= 1;
- }
-
- void
- rotxAdd(void)
- {
- rotx = (rotx + 5) % 360;
- }
-
- void
- rotxSubtract(void)
- {
- rotx = (rotx - 5) % 360;
- }
-
- void
- rotyAdd(void)
- {
- roty = (roty + 5) % 360;
- }
-
- void
- rotySubtract(void)
- {
- roty = (roty - 5) % 360;
- }
-
- void
- rotxBAdd(void)
- {
- rotx = (rotx + 45) % 360;
- }
-
- void
- rotxBSubtract(void)
- {
- rotx = (rotx - 45) % 360;
- }
-
- void
- rotyBAdd(void)
- {
- roty = (roty + 45) % 360;
- }
-
- void
- rotyBSubtract(void)
- {
- roty = (roty - 45) % 360;
- }
-
- #endif
-
- static void
- RenderSproingie(int t)
- {
- GLfloat scale, pointsize, mat_color[4] =
- {0.0, 0.0, 0.0, 1.0};
- GLdouble clipplane[4] =
- {0.0, 1.0, 0.0, 0.0};
- struct sPosColor *thisSproingie = &(positions[t]);
-
- if (thisSproingie->life < 1)
- return;
-
- glPushMatrix();
-
- if (!mono_sp) {
- mat_color[0] = thisSproingie->r;
- mat_color[1] = thisSproingie->g;
- mat_color[2] = thisSproingie->b;
- if (wireframe)
- glColor3fv(mat_color);
- else {
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_color);
- }
- }
- if (thisSproingie->frame < 0) {
- glEnable(GL_CLIP_PLANE0);
- glTranslatef((GLfloat) (thisSproingie->x),
- (GLfloat) (thisSproingie->y) +
- ((GLfloat) (thisSproingie->frame) / 9.0),
- (GLfloat) (thisSproingie->z));
- clipplane[3] = ((GLdouble) (thisSproingie->frame) / 9.0) +
- (wireframe ? 0.0 : 0.1);
- glClipPlane(GL_CLIP_PLANE0, clipplane);
- glCallList(sproingies[0]);
- glDisable(GL_CLIP_PLANE0);
- } else if (thisSproingie->frame >= BOOM_FRAME) {
- glTranslatef((GLfloat) (thisSproingie->x) + 0.5,
- (GLfloat) (thisSproingie->y) + 0.5,
- (GLfloat) (thisSproingie->z) - 0.5);
- scale = (GLfloat) (1 << (thisSproingie->frame - BOOM_FRAME));
- glScalef(scale, scale, scale);
- if (!wireframe) {
- if (!mono_sp)
- glColor3fv(mat_color);
- glDisable(GL_LIGHTING);
- }
- pointsize = (GLfloat) ((BOOM_FRAME + 8) - thisSproingie->frame) -
- (dist / 64.0);
- glPointSize((pointsize < 1.0) ? 1.0 : pointsize);
- /*-
- * PURIFY 4.0.1 reports an unitialized memory read on the next line when using
- * MesaGL 2.2. This has been tracked to MesaGL 2.2 src/points.c line 313. */
- glCallList(SproingieBoom);
- glPointSize(1.0);
- if (!wireframe) {
- glEnable(GL_LIGHTING);
- }
- } else if (thisSproingie->frame > 5) {
- glTranslatef((GLfloat) (thisSproingie->x + 1),
- (GLfloat) (thisSproingie->y - 1), (GLfloat) (thisSproingie->z - 1));
- glRotatef((GLfloat) - 90.0, 0.0, 1.0, 0.0);
- glCallList(sproingies[thisSproingie->frame - 6]);
- } else {
- glTranslatef((GLfloat) (thisSproingie->x), (GLfloat) (thisSproingie->y),
- (GLfloat) (thisSproingie->z));
- glCallList(sproingies[thisSproingie->frame]);
- }
-
- glPopMatrix();
-
- }
-
- static void
- ComputeGround()
- {
- int g_higher, g_back, g_width, g_height;
-
- /* higher: x-1, y+2, z-1 */
- /* back: x-1, y, z+1 */
-
- if (groundlevel == 0) {
- g_back = 2;
- g_width = 5;
- } else if (groundlevel == 1) {
- g_back = 4;
- g_width = 8;
- } else {
- g_back = 8;
- g_width = 16;
- }
-
- if ((g_higher = dist >> 3) < 4)
- g_higher = 4;
- if (g_higher > 16)
- g_higher = 16;
- g_height = g_higher << 1;
-
- if (rotx < -10)
- g_higher += (g_higher >> 2);
- else if (rotx > 10)
- g_higher -= (g_higher >> 2);
-
- #if 0
- if (dist > 128) {
- ++g_higher;
- ++g_back;
- g_back <<= 1;
- } else if (dist > 64) {
- ++g_higher;
- ++g_back;
- } else if (dist > 32) {
- /* nothing special */
- } else {
- if (g_higher > 2) {
- g_higher = g_back = 4;
- }
- }
- #endif
-
- /* startx, starty, startz, width, height */
- LayGround((-g_higher - g_back), (g_higher << 1), (g_back - g_higher),
- (g_width), (g_height));
- }
-
- void
- DisplaySproingies()
- {
- int t;
- GLfloat position[] =
- {8.0, 5.0, -2.0, 0.1};
-
- if (wireframe)
- glClear(GL_COLOR_BUFFER_BIT);
- else
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glPushMatrix();
- glTranslatef(0.0, 0.0, -(GLfloat) (dist) / 16.0); /* viewing transform */
- glRotatef((GLfloat) rotx, 1.0, 0.0, 0.0);
- glRotatef((GLfloat) roty, 0.0, 1.0, 0.0);
-
- if (!wireframe)
- glLightfv(GL_LIGHT0, GL_POSITION, position);
-
- #if 0 /* Show light pos */
- glPushMatrix();
- glTranslatef(position[0], position[1], position[2]);
- glColor3f(1.0, 1.0, 1.0);
- if (!wireframe) {
- glDisable(GL_LIGHTING);
- }
- glCallList(SproingieBoom);
- if (!wireframe) {
- glEnable(GL_LIGHTING);
- }
- glPopMatrix();
- #endif
-
- glTranslatef((GLfloat) sframe * (-1.0 / 12.0) - 0.75,
- (GLfloat) sframe * (2.0 / 12.0) - 0.5,
- (GLfloat) sframe * (-1.0 / 12.0) + 0.75);
-
- if (wireframe)
- ComputeGround();
-
-
- if (!wireframe)
- ComputeGround();
-
- for (t = 0; t < maxsproingies; ++t) {
- RenderSproingie(t);
- }
-
-
- glPopMatrix();
- glFlush();
-
- SproingieSwap();
- }
-
- void
- NextSproingieDisplay()
- {
- NextSproingie();
- DisplaySproingies();
- }
-
- void
- CleanupSproingies()
- {
- int t;
-
- if (SproingieBoom) {
- for (t = 0; t < 6; ++t)
- glDeleteLists(sproingies[t], 1);
-
- glDeleteLists(TopsSides, 2);
- glDeleteLists(SproingieBoom, 1);
-
- --active_screens;
- SproingieBoom = 0;
- }
- if (positions) {
- (void) free((void *) (positions));
- positions = NULL;
- }
- }
-
- void
- InitSproingies(int wfmode, int grnd, int mspr, int screen, int numscreens,
- int mono_sp)
- {
- GLfloat ambient[] =
- {0.2, 0.2, 0.2, 1.0};
- GLfloat position[] =
- {10.0, 1.0, 1.0, 10.0};
- GLfloat mat_diffuse[] =
- {0.6, 0.6, 0.6, 1.0};
- GLfloat mat_specular[] =
- {0.8, 0.8, 0.8, 1.0};
- GLfloat mat_shininess[] =
- {50.0};
-
- int t;
-
- active_screens++;
- CleanupSproingies();
-
- if (mspr < 0)
- mspr = 0;
- if (mspr >= MAXSPROING)
- mspr = MAXSPROING - 1;
-
- rotx = 0;
- roty = -45;
- dist = (16 << 2);
- sframe = 0;
- target_count = 0;
- mono_sp = mono_sp;
-
- wireframe = flatshade = 0;
-
- if (wfmode == 2)
- flatshade = 1;
- else if (wfmode)
- wireframe = 1;
-
- groundlevel = grnd;
- maxsproingies = mspr;
-
- if (maxsproingies) {
- positions = (struct sPosColor *) calloc(maxsproingies,
- sizeof (struct sPosColor));
-
- if (!(positions))
- maxsproingies = 0;
- }
- for (t = 0; t < maxsproingies; ++t) {
- positions[t].x = 0;
- positions[t].y = 0;
- positions[t].z = 0;
- positions[t].life = (-t * ((maxsproingies > 19) ? 1 : 4)) - 2;
- positions[t].frame = 0;
- }
-
- #if 0 /* Test boom */
- positions[0].x = 0;
- positions[0].y = 0;
- positions[0].z = 0;
- positions[0].life = 10;
- positions[0].frame = BOOM_FRAME;
- positions[0].r = 0.656863;
- positions[0].g = 1.0;
- positions[0].b = 0.656863;
- #endif
-
- if (!(TopsSides = build_TopsSides(wireframe)))
- (void) fprintf(stderr, "build_TopsSides\n");
-
- if (!(sproingies[0] = BuildLWO_sp(wireframe, &LWO_s1_1)))
- (void) fprintf(stderr, "BuildLWO_sp - 1\n");
- if (!(sproingies[1] = BuildLWO_sp(wireframe, &LWO_s1_2)))
- (void) fprintf(stderr, "BuildLWO_sp - 2\n");
- if (!(sproingies[2] = BuildLWO_sp(wireframe, &LWO_s1_3)))
- (void) fprintf(stderr, "BuildLWO_sp - 3\n");
- if (!(sproingies[3] = BuildLWO_sp(wireframe, &LWO_s1_4)))
- (void) fprintf(stderr, "BuildLWO_sp - 4\n");
- if (!(sproingies[4] = BuildLWO_sp(wireframe, &LWO_s1_5)))
- (void) fprintf(stderr, "BuildLWO_sp - 5\n");
- if (!(sproingies[5] = BuildLWO_sp(wireframe, &LWO_s1_6)))
- (void) fprintf(stderr, "BuildLWO_sp - 6\n");
-
- if (!(SproingieBoom = BuildLWO_sp(wireframe, &LWO_s1_b)))
- (void) fprintf(stderr, "BuildLWO_sp - b\n");
-
- if (wireframe) {
- glShadeModel(GL_FLAT);
- glDisable(GL_LIGHTING);
- } else {
- if (flatshade) {
- glShadeModel(GL_FLAT);
- position[0] = 1.0;
- position[3] = 0.0;
- }
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glDepthFunc(GL_LEQUAL);
- glEnable(GL_DEPTH_TEST);
-
- glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
- glLightfv(GL_LIGHT0, GL_POSITION, position);
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
-
- /* glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); */
- glCullFace(GL_BACK);
- glEnable(GL_CULL_FACE);
-
- glFrontFace(GL_CW);
- /* glEnable(GL_NORMALIZE); */
- }
- }
-
- /* End of sproingies.c */
-